package com.shop.shopserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.shopcommon.constant.MessageConstant;
import com.shop.shopcommon.context.SecurityContext;
import com.shop.shopcommon.exception.Base.ShoppingCartBusinessException;
import com.shop.shopcommon.result.Result;
import com.shop.shoppojo.dto.CartDTO;
import com.shop.shoppojo.dto.CartDeleteDTO;
import com.shop.shoppojo.entity.Cart;
import com.shop.shoppojo.entity.Goods;
import com.shop.shoppojo.entity.User;
import com.shop.shoppojo.vo.CartGoodsVO;
import com.shop.shoppojo.vo.CartInsertVO;
import com.shop.shoppojo.vo.CartListVO;
import com.shop.shopserver.mapper.CartMapper;
import com.shop.shopserver.mapper.GoodsMapper;
import com.shop.shopserver.mapper.UserMapper;
import com.shop.shopserver.service.CartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements CartService {
    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private UserMapper userMapper;


    /**
     * 添加购物车
     * @param cartDTO
     * @return
     * @throws IOException
     */

    public Result<CartInsertVO> add(@RequestBody CartDTO cartDTO) throws IOException {
        Long goodsId = cartDTO.getGoodsId();
        Integer goodsNum = cartDTO.getGoodsNum();
        Long userId = getUserIdByUsername().getId();

        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<Cart>()
                .eq(Cart::getGoodsId,goodsId).eq(Cart::getUserId,userId);
        Cart cart = getOne(lambdaQueryWrapper);


        log.info("cart中的session中的userId:"+userId);
        //判断请求参数是否存在 购物车内是否已有商品 无
        if (cart == null){
            log.info("购物车无对应商品");
            Cart cart1 = Cart.builder()
                    .goodsId(goodsId)
                    .goodsNum(goodsNum)
                    .userId(userId)
                    .build();
            save(cart1);
        }else {
            //判断购物车内是否已有商品 有 更新商品数量
            log.info("购物车有对应商品");
            UpdateWrapper<Cart> updateWrapper=new UpdateWrapper<>();
            int oldGoodsNum = cart.getGoodsNum();
            if (oldGoodsNum==0){
                throw new ShoppingCartBusinessException(MessageConstant.GOODS_NUM_IS_NULL);
            }
            log.info("已有数量"+oldGoodsNum);

            updateWrapper
                    .eq("goods_id",goodsId)
                    .eq("user_id",userId)
                    .set("goods_num",goodsNum+oldGoodsNum);

            cartMapper.update(null,updateWrapper);
            log.info("最新数量："+goodsNum);
            log.info("购物车内有商品:"+goodsId);
        }
        //处理返回数购物车商品总数
        LambdaQueryWrapper<Cart> cartWrapper= new LambdaQueryWrapper<Cart>()
                .eq(Cart::getUserId,userId);
        List<Cart> cartList = cartMapper.selectList(cartWrapper);
        Integer cartTotal =(cartList.size());
        log.info(String.valueOf(cartTotal));
        CartInsertVO cartInsertVO = CartInsertVO
                .builder()
                .cartTotal(cartTotal)
                .build();

        return Result.success(cartInsertVO,"加入购物车成功");
    }


    /**
     * 更新购物车商品数量
     * @param cartDTO
     * @return
     * @throws IOException
     */

//    更新购物车商品数量
    public Result<CartInsertVO> updateCartGoodsNum(@RequestBody CartDTO cartDTO) throws IOException{
        Long goodsId = cartDTO.getGoodsId();
        Integer goodsNum = cartDTO.getGoodsNum();
        Long userId = getUserIdByUsername().getId();

        LambdaQueryWrapper<Cart> lambdaQueryWrapper = new LambdaQueryWrapper<Cart>()
                .eq(Cart::getGoodsId,goodsId).eq(Cart::getUserId,userId);
        Cart cart = getOne(lambdaQueryWrapper);


        log.info("cart中的session中的userId:"+userId);

        //判断请求参数是否存在 购物车内是否已有商品 无
        if (cart == null){
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }else {
            //判断购物车内是否已有商品 有 更新商品数量
            log.info("购物车有对应商品");
            UpdateWrapper<Cart> updateWrapper=new UpdateWrapper<Cart>()
                    .eq("goods_id",goodsId)
                    .eq("user_id",userId)
                    .set("goods_num",goodsNum);
            log.info("最新数量："+goodsNum);

            cartMapper.update(null,updateWrapper);
            log.info("购物车内有商品:"+goodsId);
        }
        //处理返回数购物车商品总数
        LambdaQueryWrapper<Cart> cartWrapper= new LambdaQueryWrapper<Cart>()
                .eq(Cart::getUserId,userId);
        List<Cart> cartList = cartMapper.selectList(cartWrapper);
        Integer cartTotal =(cartList.size());
        log.info(String.valueOf(cartTotal));
        CartInsertVO cartInsertVO = CartInsertVO
                .builder()
                .cartTotal(cartTotal)
                .build();

        return Result.success(cartInsertVO,"更新购物车成功");
    }

    /**
     * 删除购物车
     * @param cartDeleteDTO
     * @return
     * @throws IOException
     */

    //删除购物车
    public Result<Cart> deleteCart(@RequestBody CartDeleteDTO cartDeleteDTO) throws IOException{
        Long userId= getUserIdByUsername().getId();
        Long goodsId= cartDeleteDTO.getGoodsId();
        List<String> cartIds=cartDeleteDTO.getCartIds();


        log.info("deleteCart中的session中的userId:"+userId);
        log.info("需要删除的订单:"+goodsId);

        //遍历购物车id并删除
        int num=0;
        for (String cartId : cartIds) {
            log.info("需要删除的订单数组形式为：" + cartId);
            LambdaQueryWrapper<Cart> wrapper = new LambdaQueryWrapper<Cart>()
                    .eq(Cart::getId, cartId)
                    .eq(Cart::getUserId, userId);
            Cart cart = getOne(wrapper);
            log.info("需要删除的购物车订单：" + cart);

            //判断是否对应id和userId有需要删除的购物车商品记录
            if (cart == null) {
                throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
            }
            //删除已存在的订单
            num = cartMapper.delete(wrapper);
        }
        String str="删除成功"+num+"条记录";
        return Result.success(null,str);
    }

    /**
     * 显示购物车
     * @param cartDTO
     * @return
     */


    //显示购物车
    public Result<CartListVO> getCartList(CartDTO cartDTO){
        log.info("cartList中的userId:"+getUserIdByUsername().getId() );
        //查询购物车内容 根据userId查询
        LambdaQueryWrapper<Cart> lambdaQueryWrapper=new LambdaQueryWrapper<Cart>()
                .eq(Cart::getUserId,getUserIdByUsername().getId());
        List<Cart> cartList=cartMapper.selectList(lambdaQueryWrapper);

        List<CartGoodsVO> cartGoodsVOList = new ArrayList<>();
        cartList.forEach(cart -> {
            //根据购物车中的goodsId查询商品信息
            Long goodsId=cart.getGoodsId();
            LambdaQueryWrapper<Goods> goodsLambdaQueryWrapper=new LambdaQueryWrapper<Goods>()
                    .eq(Goods::getId,cart.getGoodsId());
            Goods goods=goodsMapper.selectOne(goodsLambdaQueryWrapper);
            //将商品信息设置到Cart的goods中
            CartGoodsVO cartGoodsVO = CartGoodsVO
                    .builder()
                    .id(cart.getId())
                    .goodsId(cart.getGoodsId())
                    .goodsNum(cart.getGoodsNum())
                    .userId(cart.getUserId())
                    .goods(goods)
                    .build();

            cartGoodsVOList.add(cartGoodsVO);
        });
        //将cartList设置到CartList的List中
        CartListVO cartListVO=new CartListVO();
        cartListVO.setList(cartGoodsVOList);
        //设置cartTotal
        cartListVO.setCartTotal(cartList.size());
        //将cartList1设置到R的data,并返回
        return Result.success(cartListVO,"success");
    }

    /**
     * 根据用户名查询用户id
     * @return
     */
    private User getUserIdByUsername() {
        String username = SecurityContext.getUsername();
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>()
                .select(User::getId)
                .eq(User::getUsername, username);
        User user = userMapper.selectOne(queryWrapper);
        System.out.println("user" + user);
        return user;
    }
}
